package com.lengxf.pay.ali;

import cn.hutool.core.util.StrUtil;
import com.alipay.api.*;
import com.alipay.api.domain.AlipayTradeFastpayRefundQueryModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.lengxf.pay.ali.config.ALI_PayConfig;
import com.lengxf.pay.ali.config.ALI_TransactionType;
import com.lengxf.pay.ali.service.AliAppPayService;
import com.lengxf.pay.ali.service.AliWapPayService;
import com.lengxf.pay.ali.service.AliWebPayService;
import com.lengxf.pay.common.PayException;
import com.lengxf.pay.common.bean.*;
import com.lengxf.pay.common.config.GlobalObjectMapper;
import com.lengxf.pay.common.service.AbstractBasePayService;

import java.util.Map;

/**
 * 支付宝支付
 * By Lengxf 2023-10-30 11:52:07
 **/
public class ALI_PayService extends AbstractBasePayService<ALI_PayConfig> {

    private final AlipayClient alipayClient;

    public ALI_PayService(ALI_PayConfig payConfig) {
        super(payConfig);
        try {
            alipayClient = new DefaultAlipayClient(payConfig.convertToAlipayConfig());
        } catch (AlipayApiException e) {
            log.error("阿里支付初始化失败 : ", e);
            throw new RuntimeException(e);
        }
    }

    private <T extends AlipayResponse> T execute(AlipayRequest<T> request) {
        try {
            return alipayClient.pageExecute(request);
        } catch (AlipayApiException e) {
            throw new PayException(e.getErrMsg());
        }
    }

    @Override
    public String toPay(PayOrder payOrder) {
        String payWay = StrUtil.isBlank(payOrder.getPayWay()) ? ALI_TransactionType.WAP.toString() : payOrder.getPayWay();
        ALI_TransactionType transactionType = ALI_TransactionType.toEnum(payWay);
        AlipayRequest<?> request = switch (transactionType) {
            case WAP -> new AliWapPayService(getPayConfig()).toPay(payOrder);
            case WEB -> new AliWebPayService(getPayConfig()).toPay(payOrder);
            case APP -> new AliAppPayService(getPayConfig()).appPay(payOrder);
            default -> throw new PayException("支付方式调用错误");
        };
        AlipayResponse result = execute(request);
        if (result.isSuccess()) {
            return result.getBody();
        }
        throw new PayException(String.format("(支付宝)获取支付链接失败,错误码{ %s },错误信息{ %s }",
                result.getSubCode(), result.getSubMsg()));
    }

    @Override
    public Map<String, Object> query(QueryOrder queryOrder) {
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();
        model.setOutTradeNo(queryOrder.getOrderNo());
        request.setBizModel(model);
        AlipayTradeQueryResponse result = execute(request);
        return GlobalObjectMapper.beanToMap(result);
    }

    @Override
    public Map<String, Object> refund(RefundOrder refundOrder) {
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setOutTradeNo(refundOrder.getOrderNo());
        model.setRefundAmount(String.valueOf(refundOrder.getAmount()));
        request.setBizModel(model);
        AlipayTradeRefundResponse result = execute(request);
        return GlobalObjectMapper.beanToMap(result);
    }

    @Override
    public Map<String, Object> refundQuery(RefundOrderQuery refundOrderQuery) {
        AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
        AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();
        model.setOutTradeNo(refundOrderQuery.getOrderNo());
        model.setOutRequestNo(refundOrderQuery.getRefundOrderNo());
        request.setBizModel(model);
        AlipayTradeFastpayRefundQueryResponse result = execute(request);
        return GlobalObjectMapper.beanToMap(result);
    }

    @Override
    public Map<String, Object> payBack(CallBackParam ayBackParam) {
        return null;
    }

}
